package com.bree.erp.entity;

import java.util.Collection;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@NamedQueries(
{
	@NamedQuery(name = PurchaseRequisition.QUERY_FIND_ALL_PURCHASEREQUISTION, 
			query = "SELECT p FROM PurchaseRequisition p"),
	@NamedQuery(name = PurchaseRequisition.QUERY_FIND_USER_PURCHASEREQUISTION, 
			query = "SELECT p FROM PurchaseRequisition p"),
	@NamedQuery(name = PurchaseRequisition.QUERY_FIND_USER_PURCHASEREQUISTIONAPPROVER,
			query = "SELECT p FROM PurchaseRequisition p"),
	@NamedQuery(name = PurchaseRequisition.QUERY_FIND_PURCHASEREQUISTION_PER_STATUS,
			query = "SELECT p FROM PurchaseRequisition p WHERE p.status = :status")}
)
@Entity
public class PurchaseRequisition implements CrudId<Long> {

	public final static String QUERY_FIND_ALL_PURCHASEREQUISTION = "findAllPurchaseRequisitions";
	public final static String QUERY_FIND_USER_PURCHASEREQUISTION = "findUserPR";
	public final static String QUERY_FIND_USER_PURCHASEREQUISTIONAPPROVER = "findUserPrApprover";
	public final static String QUERY_FIND_PURCHASEREQUISTION_PER_STATUS = "findPurchaseRequisitionsPerSatus";
	
	@Id
	@GeneratedValue(strategy=GenerationType.SEQUENCE)
	private Long id;
	
	@ManyToOne
	private Project project;
	
	private String description;
	
	@Temporal(TemporalType.DATE)
	private Date requisitionDate;
	
	@OneToMany(mappedBy="purchaseRequisition")
	private Collection<ItemRequest> requests;
	
	@OneToMany(mappedBy="purchaseRequisition")
	private Collection<PurchaseOrder> orders;
	
	@Enumerated(EnumType.STRING)
	private Status status;
	
	@OneToOne
	private User createdBy;
	@OneToOne
	private User updatedBy;
	@OneToOne
	private User approvedBy;
	@OneToOne
	private User rejectedBy;

	@Temporal(TemporalType.TIMESTAMP)
	private Date created;
	@Temporal(TemporalType.TIMESTAMP)
	private Date updated;
	@Temporal(TemporalType.TIMESTAMP)
	private Date approved;
	@Temporal(TemporalType.TIMESTAMP)
	private Date rejected;
	
	@Override
	public int hashCode() {
		return this.id == null ? 0 : this.id.hashCode();
	}
	
	@Override
	public boolean equals(Object obj) {
		
		if(obj instanceof PurchaseRequisition) {
			PurchaseRequisition that = (PurchaseRequisition) obj;
			return this.id != null && this.id.equals(that.id);
		}
		
		return false;
	}
	
	
	public static void copy(PurchaseRequisition source, PurchaseRequisition target) {

		//target.setPrAudit(source.getPrAudit());
		target.setDescription(source.getDescription());
		target.setId(source.getId());
		target.setProject(source.getProject());
		target.setRequests(source.getRequests());
		target.setRequisitionDate(source.getRequisitionDate());
		target.setStatus(source.getStatus());
	}


	public void auditCreate(User user) {
		this.setCreatedBy(user);
		this.setCreated(new Date());
		
	}

	public void auditUpdate(User user) {
		this.setUpdatedBy(user);
		this.setUpdated(new Date());
	}

	public void auditApprove(User user) {
		this.setApprovedBy(user);
		this.setApproved(new Date());
	}

	public void auditReject(User user) {
		this.setRejectedBy(user);
		this.setRejected(new Date());
	}
	
	/**
	 * @return the id
	 */
	public Long getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @param description the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * @return the requisitionDate
	 */
	public Date getRequisitionDate() {
		return requisitionDate;
	}

	/**
	 * @param requisitionDate the requisitionDate to set
	 */
	public void setRequisitionDate(Date requisitionDate) {
		this.requisitionDate = requisitionDate;
	}

	/**
	 * @return the requests
	 */
	public Collection<ItemRequest> getRequests() {
		return requests;
	}

	/**
	 * @param requests the requests to set
	 */
	public void setRequests(Collection<ItemRequest> requests) {
		this.requests = requests;
	}
	
	/**
	 * @return the status
	 */
	public Status getStatus() {
		return status;
	}

	/**
	 * @param status the status to set
	 */
	public void setStatus(Status status) {
		this.status = status;
	}
	
	/**
	 * @return the project
	 */
	public Project getProject() {
		return project;
	}

	/**
	 * @param project the project to set
	 */
	public void setProject(Project project) {
		this.project = project;
	}

	/**
	 * @return the createdBy
	 */
	public User getCreatedBy() {
		return createdBy;
	}

	/**
	 * @param createdBy the createdBy to set
	 */
	public void setCreatedBy(User createdBy) {
		this.createdBy = createdBy;
	}

	/**
	 * @return the updatedBy
	 */
	public User getUpdatedBy() {
		return updatedBy;
	}

	/**
	 * @param updatedBy the updatedBy to set
	 */
	public void setUpdatedBy(User updatedBy) {
		this.updatedBy = updatedBy;
	}

	/**
	 * @return the approvedBy
	 */
	public User getApprovedBy() {
		return approvedBy;
	}

	/**
	 * @param approvedBy the approvedBy to set
	 */
	public void setApprovedBy(User approvedBy) {
		this.approvedBy = approvedBy;
	}

	/**
	 * @return the rejectedBy
	 */
	public User getRejectedBy() {
		return rejectedBy;
	}

	/**
	 * @param rejectedBy the rejectedBy to set
	 */
	public void setRejectedBy(User rejectedBy) {
		this.rejectedBy = rejectedBy;
	}

	/**
	 * @return the created
	 */
	public Date getCreated() {
		return created;
	}

	/**
	 * @param created the created to set
	 */
	public void setCreated(Date created) {
		this.created = created;
	}

	/**
	 * @return the updated
	 */
	public Date getUpdated() {
		return updated;
	}

	/**
	 * @param updated the updated to set
	 */
	public void setUpdated(Date updated) {
		this.updated = updated;
	}

	/**
	 * @return the approved
	 */
	public Date getApproved() {
		return approved;
	}

	/**
	 * @param approved the approved to set
	 */
	public void setApproved(Date approved) {
		this.approved = approved;
	}

	/**
	 * @return the rejected
	 */
	public Date getRejected() {
		return rejected;
	}

	/**
	 * @param rejected the rejected to set
	 */
	public void setRejected(Date rejected) {
		this.rejected = rejected;
	}

	/**
	 * @return the orders
	 */
	public Collection<PurchaseOrder> getOrders() {
		return orders;
	}

	/**
	 * @param orders the orders to set
	 */
	public void setOrders(Collection<PurchaseOrder> orders) {
		this.orders = orders;
	}
}
